package com.zcoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcoj.core.model.ApiResponse;
import com.zcoj.core.model.PageData;
import com.zcoj.core.model.PageWrap;
import com.zcoj.mapper.GroupMapper;
import com.zcoj.mapper.GroupMemberMapper;
import com.zcoj.mapper.GroupRegisterMapper;
import com.zcoj.pojo.Dto.*;
import com.zcoj.pojo.Vo.GroupMainReqVO;
import com.zcoj.pojo.Vo.GroupMemberRegisterVO;
import com.zcoj.pojo.Vo.GroupPageVO;
import com.zcoj.security.dto.LoginUser;
import com.zcoj.service.*;
import com.zcoj.util.RedisCaches;
import com.zcoj.util.WrapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Service实现
 * @author 剩xia的盛夏
 * @date 2023/02/24 16:16
 */
@Service
@Slf4j
public class GroupServiceImpl implements GroupService {


    @Autowired
    private RedisCaches redisCaches;
    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private GroupMemberMapper groupMemberMapper;

    @Autowired
    private GroupMemberService groupMemberService;

    @Autowired
    private GroupProblemService groupProblemService;

    @Autowired
    private GroupRegisterService groupRegisterService;

    @Autowired
    private GroupAnnouncementService groupAnnouncementService;

    @Autowired
    private GroupRegisterMapper groupRegisterMapper;

    @Override
    public Integer create(Group group) {
        LoginUser loginUser = redisCaches.getLoginUser();
        group.setUid(loginUser.getId());
        group.setOwner(loginUser.getUsername());
        group.setStatus(0);
        groupMapper.insert(group);
        if(Objects.nonNull(group.getId())){
            GroupRegister groupRegister = new GroupRegister();
            groupRegister.setUid(loginUser.getId());
            groupRegister.setGid(group.getId());
            groupRegister.setStatus(1);//0x,1审核，2通过
            groupRegisterMapper.insert(groupRegister);
        }
        return group.getId();
    }

    @Override
    public Integer adminCreate(Group group) {
        LoginUser loginUser = redisCaches.getLoginUser();
        group.setUid(loginUser.getId());
        group.setOwner(loginUser.getUsername());
        group.setStatus(1);
        groupMapper.insert(group);
        if(Objects.nonNull(group.getId())){
            GroupRegister groupRegister = new GroupRegister();
            groupRegister.setUid(loginUser.getId());
            groupRegister.setGid(group.getId());
            groupRegister.setStatus(2);//0x,1审核，2通过
            groupRegisterMapper.insert(groupRegister);
        }
        return group.getId();
    }


    @Override
    public Integer deleteById(Integer id) {
        GroupAnnouncement groupAnnouncement = new GroupAnnouncement();
        groupAnnouncement.setGid(id);
        List<GroupAnnouncement> groupAnnouncements = groupAnnouncementService.findList(groupAnnouncement);
        for (GroupAnnouncement announcement : groupAnnouncements) {
            groupAnnouncementService.deleteById(announcement.getId());
        }

        GroupMember groupMember = new GroupMember();
        groupMember.setGid(id);
        List<GroupMember> groupMembers = groupMemberService.findList(groupMember);
        for (GroupMember member : groupMembers) {
            groupMemberService.deleteById(member.getId());
        }
        GroupProblem groupProblem = new GroupProblem();
        groupProblem.setGid(id);
        List<GroupProblem> groupProblems = groupProblemService.findList(groupProblem);
        for (GroupProblem problem : groupProblems) {
            groupProblemService.deleteById(problem.getId());
        }
        GroupRegister groupRegister = new GroupRegister();
        groupRegister.setGid(id);
        List<GroupRegister> groupRegisters = groupRegisterService.findList(groupRegister);
        for (GroupRegister register : groupRegisters) {
            groupRegisterService.deleteById(register.getId());
        }
        return groupMapper.deleteById(id);
    }

    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) return;
        groupMapper.deleteBatchIds(ids);
    }

    @Override
    public Integer updateById(Group group) {
        return groupMapper.updateById(group);
    }

    @Override
    public void updateByIdInBatch(List<Group> groups) {
        if (CollectionUtils.isEmpty(groups)) return;
        for (Group group: groups) {
            this.updateById(group);
        }
    }

    @Override
    public Group findById(Integer id) {
        return groupMapper.selectById(id);
    }

    @Override
    public Group findOne(Group group) {
        Wrapper<Group> wrapper = new QueryWrapper<>(group);
        return groupMapper.selectOne(wrapper);
    }

    @Override
    public List<Group> findList(Group group) {
        Wrapper<Group> wrapper = new QueryWrapper<>(group);
        return groupMapper.selectList(wrapper);
    }
  
    @Override
    public PageData<Group> findPage(PageWrap<Group> pageWrap) {
        IPage<Group> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        Group group = WrapperUtil.blankToNull(pageWrap.getModel());
        QueryWrapper<Group> queryWrapper = new QueryWrapper<>();
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        if(Objects.nonNull(group.getName())){
            queryWrapper.like("name",group.getName());
        }
        if(Objects.nonNull(group.getAuth())){
            queryWrapper.eq("auth",group.getAuth());
        }
        if(Objects.nonNull(group.getStatus())){
            queryWrapper.eq("status",group.getStatus());
        }
        queryWrapper.select("id","name","face_url","owner","auth","status","create_time","update_time");
        return PageData.from(groupMapper.selectPage(page, queryWrapper));
    }

    @Override
    public PageData<GroupPageVO> findPageVo(PageWrap<Group> pageWrap) {
        LoginUser loginUser = redisCaches.getLoginUser();
        IPage<Group> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        Group group = WrapperUtil.blankToNull(pageWrap.getModel());
        QueryWrapper<Group> queryWrapper = new QueryWrapper<>();
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase("DESC")) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        //无权限 取消团队查看
        if(Objects.nonNull(group.getStatus())){
            queryWrapper.like("status",group.getStatus());
        }

        if(Objects.nonNull(group.getName())){
            queryWrapper.like("name",group.getName());
        }
        if(Objects.nonNull(group.getAuth())&&group.getAuth()!=0){
            queryWrapper.eq("auth",group.getAuth());
        }

        queryWrapper.select("id","face_url","name","brief","owner","auth");
        IPage<Group> groupIPage = groupMapper.selectPage(page, queryWrapper);


        List<Integer> gids=new ArrayList<>();
        if(loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("admin")){
            QueryWrapper<Group> queryWrapperG=new QueryWrapper<>();
            queryWrapperG.select("id");
            List<Group> groups = groupMapper.selectList(queryWrapperG);
            for (Group group1 : groups) {
                gids.add(group1.getId());
            }
        }else {
            if(Objects.nonNull(group.getUid())){
                QueryWrapper<GroupRegister> groupRegisterQueryWrapper=new QueryWrapper<>();
                groupRegisterQueryWrapper.eq("uid",group.getUid());
                groupRegisterQueryWrapper.select("gid");
                List<GroupRegister> groupRegisterList = groupRegisterMapper.selectList(groupRegisterQueryWrapper);
                for (GroupRegister groupRegister : groupRegisterList) {
                    gids.add(groupRegister.getGid());
                }
            }
        }


        // dto -> vo
        List<GroupPageVO> list=new ArrayList<>();
        for (Group record : groupIPage.getRecords()) {
            GroupPageVO groupPageVO = new GroupPageVO();
            groupPageVO.setId(record.getId());
            groupPageVO.setFaceUrl(record.getFaceUrl());
            groupPageVO.setName(record.getName());
            groupPageVO.setBrief(record.getBrief());
            groupPageVO.setOwner(record.getOwner());
            groupPageVO.setAuth(record.getAuth());

            QueryWrapper<GroupMember> groupMemberQueryWrapper=new QueryWrapper<>();
            if(gids.contains(record.getId())){
                groupPageVO.setStatus(3);
            }else {
                groupMemberQueryWrapper.eq("uid",loginUser.getId()).eq("gid",record.getId());
                GroupMember groupMember = groupMemberMapper.selectOne(groupMemberQueryWrapper);
                if( Objects.nonNull(groupMember)){
                    groupPageVO.setStatus(groupMember.getAuth());
                }else {
                    groupPageVO.setStatus(0);
                }
            }
            queryWrapper.clear();
            queryWrapper.eq("gid",record.getId());
            Integer number = groupMemberMapper.selectCount(groupMemberQueryWrapper);
            groupPageVO.setMemberNumber(number);
            list.add(groupPageVO);
        }

        IPage<GroupPageVO> groupPageVOIPage=new Page<>();
        groupPageVOIPage.setRecords(list);
        groupPageVOIPage.setCurrent(groupIPage.getCurrent());
        groupPageVOIPage.setPages(groupIPage.getPages());
        groupPageVOIPage.setTotal(groupIPage.getTotal());
        groupPageVOIPage.setSize(groupPageVOIPage.getSize());
        return PageData.from(groupPageVOIPage);
    }

    @Override
    public Boolean memberRegister(GroupMemberRegisterVO groupMemberRegisterVO) {
        QueryWrapper<Group> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",groupMemberRegisterVO.getGid());
        Group group = groupMapper.selectOne(queryWrapper);
        LoginUser loginUser = redisCaches.getLoginUser();
        if(Objects.nonNull(group)){
            //public
            if(group.getAuth()==1){
                if(Objects.nonNull(loginUser)){
                    QueryWrapper<GroupMember> groupMemberQueryWrapper=new QueryWrapper<>();
                    groupMemberQueryWrapper.eq("uid",loginUser.getId()).eq("gid",groupMemberRegisterVO.getGid());
                    GroupMember groupMember = groupMemberMapper.selectOne(groupMemberQueryWrapper);
                    if(Objects.isNull(groupMember)){
                            groupMember=new GroupMember();
                            groupMember.setUid(loginUser.getId());
                            groupMember.setGid(groupMemberRegisterVO.getGid());
                            groupMember.setAuth(3);
                            int status = groupMemberMapper.insert(groupMember);
                            return status != 0;

                    }else {
                        return false;
                    }
                }else {
                    return false;
                }
            }else {
                if(Objects.nonNull(loginUser)){
                    QueryWrapper<GroupMember> groupMemberQueryWrapper=new QueryWrapper<>();
                    groupMemberQueryWrapper.eq("uid",loginUser.getId()).eq("gid",groupMemberRegisterVO.getGid());
                    GroupMember groupMember = groupMemberMapper.selectOne(groupMemberQueryWrapper);
                    if(Objects.isNull(groupMember)){

                        if(group.getCode().equals(groupMemberRegisterVO.getCode())){
                            groupMember=new GroupMember();
                            groupMember.setUid(loginUser.getId());
                            groupMember.setGid(groupMemberRegisterVO.getGid());
                            groupMember.setAuth(1);
                            int status = groupMemberMapper.insert(groupMember);
                            return status != 0;
                        }else {
                            return false;
                        }

                    }else {
                        return false;
                    }
                }else {
                    return false;
                }
            }
        }else {
            return false;
        }


    }

    @Override
    public ApiResponse groupMainData(GroupMainReqVO groupMainReqVO) {
        LoginUser loginUser = redisCaches.getLoginUser();
        if(Objects.nonNull(groupMainReqVO)&&Objects.nonNull(loginUser)&& Objects.equals(loginUser.getId(), groupMainReqVO.getUid())){
            if(loginUser.getPermission().contains("super_admin")||loginUser.getPermission().contains("admin")){
                Group group = groupMapper.selectById(groupMainReqVO.getGid());
                return ApiResponse.success("",group);
            }else {
                QueryWrapper<GroupMember> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("uid",groupMainReqVO.getUid()).eq("gid",groupMainReqVO.getGid());
                GroupMember groupMember = groupMemberMapper.selectOne(queryWrapper);
                if(Objects.nonNull(groupMember)){
                    Group group = groupMapper.selectById(groupMainReqVO.getGid());
                    return ApiResponse.success("",group);
                }else {
                    return ApiResponse.failed("请先申请加入团队！！！");
                }
            }
        }
        return ApiResponse.failed("参数错误！！！");
    }

    @Override
    public Boolean quitGroup(Integer id) {
        LoginUser loginUser = redisCaches.getLoginUser();
        if(Objects.nonNull(id)&&Objects.nonNull(loginUser)){
         QueryWrapper<GroupMember> queryWrapper=new QueryWrapper<>();
         queryWrapper.eq("uid",loginUser.getId()).eq("gid",id);
         GroupMember groupMember = groupMemberMapper.selectOne(queryWrapper);
         if(Objects.nonNull(groupMember)){
             int deleteById = groupMemberMapper.deleteById(groupMember.getId());
             if(deleteById>0){
                 return true;
             }else {
                 return false;
             }
         }else {
             return false;
         }
        }else {
            return false;
        }
    }

    @Override
    public long count(Group group) {
        Wrapper<Group> wrapper = new QueryWrapper<>(group);
        return groupMapper.selectCount(wrapper);
    }
}
